var tgd = tgd || {};
tgd.Utilities = tgd.Utilities || {};
tgd.Utilities.Calendar = tgd.Utilities.Calendar || {};

tgd.Utilities.Calendar.Month = function (year, month) {
	var MS_PER_DAY = 86400000;  //milliseconds per day

	var _now = new Date();
	var _weeks = [];
	
	this._year = year;
	this._month = month;

	this._firstDayOfMonth = new Date(this._year, this._month, 1);
	this._firstDayOfWeek = this._firstDayOfMonth.getDay();
	this._lastDayOfMonth = new Date(new Date(this._year, this._month + 1, 1).getTime() - MS_PER_DAY);

	if (tgd.Utilities.Calendar.Month._initialized === undefined) {

		tgd.Utilities.Calendar.Month.prototype.getMonthName = function() {
			return tgd.Utilities.Calendar.MonthNames.getMonthName(this._month);
		}

		tgd.Utilities.Calendar.Month.prototype.getYear = function() {
			return this._year;
		}

		tgd.Utilities.Calendar.Month.prototype.getMonth = function() {
			return this._month;
		}

		tgd.Utilities.Calendar.Month.prototype.getFirstDayOfWeek = function() {
			return this._firstDayOfWeek;
		}

		tgd.Utilities.Calendar.Month.prototype.getNumberOfDaysInMonth = function() {
			return this._lastDayOfMonth.getDate();
		}

		tgd.Utilities.Calendar.Month._initialized = true;
	}

	var getNumberOfDaysInLastMonth = function() {
		return new Date((new Date()).setDate(1) - MS_PER_DAY).getDate();
	}

	this.getWeeks = function() {
		return _weeks;
	}

	var isCurrentMonth = (this._year == _now.getFullYear() && this._month == _now.getMonth());

	var cur = 0;
	var day
	for (var i = 0; i < 6; ++i) {  //6 weeks in the calendar
		_weeks[i] = { days: [] };

		for (var j = 0; j < 7; ++j) {  //7 days per week
			if (cur === 0 && j === this.getFirstDayOfWeek() && !(j === 0 && i === 0)) {
				++cur;
			}

			if (cur === 0) {
				day = {
					day: getNumberOfDaysInLastMonth() - (this.getFirstDayOfWeek() === 0 ? 7 : this.getFirstDayOfWeek()) + j + 1,
					isCurrentMonth: false,
					isCurrentDay: false
				};
			} else if (cur > this.getNumberOfDaysInMonth()) {
				day = {
					day: cur - this.getNumberOfDaysInMonth(),
					isCurrentMonth: false,
					isCurrentDay: false
				}
				++cur;
			} else {
				day = {
					day: cur,
					isCurrentMonth: true,
					isCurrentDay: isCurrentMonth && cur == _now.getDate()
				}
				++cur;
			}

			_weeks[i].days[j] = day;
		}
	}
}
